<template>
	<div class="sku-attribute-selector-wrapper">
		<div class="attribute-selector-view">
			<!-- 滚动容器 -->
			<div class="scroll-container">
				<!-- 已选择的属性展示 - 固定在顶部 -->
				<div class="selected-attributes-display">
					<el-text class="selected-label">已选规格：</el-text>
					<el-text :type="selectedValueIds.size > 0 ? 'primary' : 'info'">
						{{ selectedAttributesText }}
					</el-text>
				</div>

				<!-- 属性选择器内容 -->
				<div class="attributes-container">
					<template v-if="attributeGroups.length === 0">
						<el-empty description="该物料暂无属性数据" />
					</template>

					<template v-else>
						<div v-for="group in attributeGroups" :key="group.name" class="attribute-group">
							<div class="attribute-name">
								<el-text class="attr-label">{{ group.name }}</el-text>
								<el-button v-if="!disabled" link size="small" type="primary" class="attr-edit" @click="onAttribute(group)">
									<el-icon><Edit /></el-icon>
									<span>编辑</span>
								</el-button>
							</div>
							<div class="attribute-values">
								<div
									v-for="value in group.values"
									:key="value.id"
									:class="[
										'attribute-value-item',
										{ 'is-selected': isValueSelected(value.id) },
										{ 'is-key-attribute': group.isKeyAttribute },
										{ 'is-disabled': disabled },
									]"
									@click="!disabled && toggleValue(value.id)"
								>
									<span class="value-text">{{ value.text }}</span>
									<i v-if="isValueSelected(value.id)" class="check-icon el-icon-check"></i>
								</div>
							</div>
						</div>
					</template>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, watch, computed, defineAsyncComponent } from 'vue';
import { Edit } from '@element-plus/icons-vue';
import { SysMaterialAttributeApi } from '/@/views/supplychain/sysmaterialattribute/api';
import other from '/@/utils/other';

const EditDialog = defineAsyncComponent(() => import('/@/views/supplychain/sysmaterialattribute/edit.vue'));

/**
 * 属性值接口
 */
interface AttributeValue {
	id: string;
	text: string;
}

/**
 * 属性分组接口
 */
interface AttributeGroup {
	id: string | null; // 属性ID
	name: string;
	isKeyAttribute: boolean;
	values: AttributeValue[];
}

/**
 * 外部数据项接口（从后端返回的数据格式）
 */
interface ExternalDataItem {
	AttributeId?: string; // 属性ID
	Value: string; // 属性值 ID
	Text: string; // 格式："属性名: 属性值"
	IsKeyAttribute?: boolean; // 是否为关键属性
}

// Props 定义
const props = defineProps<{
	/** 物料ID - 如果提供则组件内部自动加载属性数据 */
	materialId?: string | null;
	/** 外部属性数据列表（格式：[{ Value: "id", Text: "属性名: 属性值", IsKeyAttribute: true/false }]） - 可选，用于向后兼容 */
	externalData?: ExternalDataItem[];
	/** 已选中的属性值 ID 列表（支持数组或包含 SelectedAttrIds/SelectedAttributesIds 字段的对象） */
	selectedIds?: string[] | any;
	/** 是否为采购场景（true: 只显示关键属性, false: 显示所有属性） */
	isPurchaseScenario?: boolean;
	/** 是否禁用（详情页查看模式） */
	disabled?: boolean;
}>();

// Emits 定义
const emit = defineEmits<{
	/** 选中的属性值 ID 发生变化 */
	(e: 'change', selectedIds: string[]): void;
	/** 验证状态变化（是否所有关键属性都已选择） */
	(e: 'validate', isValid: boolean, missingAttributes: string[]): void;
}>();

// 内部状态：当前选中的属性值 ID 集合
const selectedValueIds = ref<Set<string>>(new Set());

// 内部状态：从接口加载的属性数据
const internalAttributeData = ref<ExternalDataItem[]>([]);

// 加载状态
const loading = ref(false);

/**
 * 计算属性：标准化 selectedIds，自动处理后端可能返回的不同字段名
 * 支持：
 * 1. 直接传入数组：['id1', 'id2']
 * 2. 传入对象，包含 SelectedAttrIds 字段
 * 3. 传入对象，包含 SelectedAttributesIds 字段
 */
const normalizedSelectedIds = computed<string[]>(() => {
	const ids = props.selectedIds;

	// 情况1: 如果是数组，直接返回
	if (Array.isArray(ids)) {
		return ids;
	}

	// 情况2: 如果是对象，尝试从常见字段中提取数组
	if (ids && typeof ids === 'object') {
		// 尝试多个可能的字段名（优先级从高到低）
		const possibleFields = ['SelectedAttrIds', 'SelectedAttributesIds', 'selectedAttrIds', 'selectedAttributesIds'];

		for (const field of possibleFields) {
			const value = ids[field];
			if (Array.isArray(value)) {
				return value;
			}
		}
	}

	// 情况3: 其他情况返回空数组
	return [];
});

/**
 * 从接口加载物料属性数据
 */
const loadMaterialAttributes = async (materialId: string | null) => {
	if (!materialId) {
		internalAttributeData.value = [];
		return;
	}

	try {
		loading.value = true;
		const response: any = await SysMaterialAttributeApi().search({
			MaterialId: materialId,
		});

		const attributeValues: ExternalDataItem[] = [];
		if (response.Data && Array.isArray(response.Data)) {
			response.Data.forEach((attr: any) => {
				if (attr.Values && Array.isArray(attr.Values)) {
					attr.Values.forEach((value: any) => {
						attributeValues.push({
							AttributeId: attr.ID, // 添加属性ID
							Value: value.ID,
							Text: `${attr.Name}: ${value.Value}`,
							IsKeyAttribute: attr.IsKeyAttribute || false,
						});
					});
				}
			});
		}

		internalAttributeData.value = attributeValues;
	} catch (error) {
		console.error('SkuAttributeSelector: 加载物料属性失败', error);
		internalAttributeData.value = [];
	} finally {
		loading.value = false;
	}
};

/**
 * 计算属性：获取最终使用的属性数据（优先使用 externalData，如果没有则使用内部加载的数据）
 */
const finalAttributeData = computed<ExternalDataItem[]>(() => {
	// 如果提供了 externalData，优先使用（向后兼容）
	if (props.externalData && props.externalData.length > 0) {
		return props.externalData;
	}
	// 否则使用内部加载的数据
	return internalAttributeData.value;
});

/**
 * 计算属性：将属性数据转换为分组结构
 */
const attributeGroups = computed<AttributeGroup[]>(() => {
	const dataSource = finalAttributeData.value;
	if (!dataSource || dataSource.length === 0) {
		return [];
	}

	// 使用 Map 来分组
	const groupMap = new Map<string, AttributeGroup>();

	dataSource.forEach((item) => {
		// 如果是采购场景且不是关键属性，则跳过
		if (props.isPurchaseScenario && !item.IsKeyAttribute) {
			return;
		}

		// 解析 "属性名: 属性值" 格式
		const parts = item.Text.split(':').map((p) => p.trim());
		if (parts.length !== 2) {
			console.warn('SkuAttributeSelector: 无效的属性格式', item.Text, item);
			return;
		}

		const [attrName, attrValue] = parts;

		// 如果分组不存在，创建新分组
		if (!groupMap.has(attrName)) {
			groupMap.set(attrName, {
				id: item.AttributeId || null, // 保存属性ID
				name: attrName,
				isKeyAttribute: item.IsKeyAttribute || false,
				values: [],
			});
		}

		// 添加属性值到分组
		groupMap.get(attrName)!.values.push({
			id: item.Value,
			text: attrValue,
		});
	});

	return Array.from(groupMap.values());
});

/**
 * 已选属性文本 - 按照属性原始顺序展示
 */
const selectedAttributesText = computed(() => {
	if (selectedValueIds.value.size === 0) return '未选择';

	const selectedTexts: string[] = [];

	// 按照 attributeGroups 的顺序遍历
	attributeGroups.value.forEach((group) => {
		const selectedValue = group.values.find((v) => selectedValueIds.value.has(v.id));
		if (selectedValue) {
			selectedTexts.push(`${group.name}: ${selectedValue.text}`);
		}
	});

	return selectedTexts.join(' / ');
});

/**
 * 计算属性：未选择的关键属性列表
 */
const missingKeyAttributes = computed<string[]>(() => {
	const missing: string[] = [];

	// 遍历所有关键属性分组
	attributeGroups.value.forEach((group) => {
		if (group.isKeyAttribute) {
			// 检查该分组下是否有任何值被选中
			const hasSelected = group.values.some((v) => selectedValueIds.value.has(v.id));
			if (!hasSelected) {
				missing.push(group.name);
			}
		}
	});

	return missing;
});

/**
 * 计算属性：是否所有关键属性都已选择
 */
const isKeyAttributesValid = computed<boolean>(() => {
	return missingKeyAttributes.value.length === 0;
});

/**
 * 判断某个属性值是否已选中
 */
const isValueSelected = (valueId: string): boolean => {
	return selectedValueIds.value.has(valueId);
};

/**
 * 切换属性值的选中状态（单选模式：每个属性分组只能选择一个值）
 */
const toggleValue = (valueId: string) => {
	// 找到当前值所属的属性分组
	const currentGroup = attributeGroups.value.find((group) => group.values.some((v) => v.id === valueId));

	if (!currentGroup) {
		console.warn('SkuAttributeSelector: 未找到属性分组', valueId);
		return;
	}

	// 如果点击的是已选中的值，则取消选中
	if (selectedValueIds.value.has(valueId)) {
		selectedValueIds.value.delete(valueId);
	} else {
		// 先移除该分组下所有已选中的值（实现单选）
		currentGroup.values.forEach((v) => {
			selectedValueIds.value.delete(v.id);
		});

		// 再添加新选中的值
		selectedValueIds.value.add(valueId);
	}

	// 触发变化事件
	emit('change', Array.from(selectedValueIds.value));
};

/**
 * 打开属性编辑弹窗
 */
const onAttribute = (group: AttributeGroup) => {
	if (!group.id) {
		console.warn('SkuAttributeSelector: 属性ID不存在，无法打开编辑弹窗');
		return;
	}
	// 使用 other.openDialog 打开编辑弹窗
	other.openDialog('修改属性', EditDialog, { ID: group.id }, () => {
		// 弹窗关闭后重新加载属性数据
		if (props.materialId) {
			loadMaterialAttributes(props.materialId);
		}
	});
};
/**
 * 监听标准化后的选中 ID 列表，同步到内部状态
 * 使用 normalizedSelectedIds 计算属性，自动处理字段映射
 */
watch(
	normalizedSelectedIds,
	(newIds) => {
		if (newIds && newIds.length > 0) {
			selectedValueIds.value = new Set(newIds);
		} else {
			selectedValueIds.value = new Set();
		}
	},
	{ immediate: true }
);

/**
 * 监听 materialId 变化，自动加载属性数据
 */
watch(
	() => props.materialId,
	async (newMaterialId, oldMaterialId) => {
		await loadMaterialAttributes(newMaterialId || null);
		// 只在 materialId 真正变化时清空选中状态（不包括初始化和有外部 selectedIds 的情况）
		if (oldMaterialId !== undefined && newMaterialId !== oldMaterialId && (!props.selectedIds || props.selectedIds.length === 0)) {
			selectedValueIds.value.clear();
			emit('change', []);
		}
	},
	{ immediate: true }
);

/**
 * 监听外部数据变化，清空选中状态（向后兼容）
 */
watch(
	() => props.externalData,
	() => {
		if (props.externalData && props.externalData.length > 0) {
			// 只有当使用 externalData 模式时才清空选中状态
			selectedValueIds.value.clear();
			emit('change', []);
		}
	}
);

/**
 * 监听验证状态变化，触发验证事件
 */
watch(
	[isKeyAttributesValid, missingKeyAttributes],
	([isValid, missing]) => {
		emit('validate', isValid, missing);
	},
	{ immediate: true }
);
</script>

<style scoped lang="scss">
// 最外层容器 - 铺满宽度，带边框和背景
.sku-attribute-selector-wrapper {
	width: 100%;
	border: 1px solid var(--el-border-color-light);
	border-radius: 8px;
	background: var(--el-fill-color-blank);
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
	transition: all 0.3s;

	&:hover {
		box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
		border-color: var(--el-color-primary-light-5);
	}
}

.attribute-selector-view {
	width: 100%;
	height: 100%;
	overflow: hidden;
	padding: 0;

	.scroll-container {
		max-height: 450px;
		overflow-y: auto;
		overflow-x: hidden;

		// 自定义滚动条样式
		&::-webkit-scrollbar {
			width: 4px;
			height: 4px;
		}

		&::-webkit-scrollbar-track {
			background: var(--el-fill-color-lighter);
			border-radius: 2px;
			margin: 2px 0;
		}

		&::-webkit-scrollbar-thumb {
			background: var(--el-border-color);
			border-radius: 2px;
			transition: background 0.2s;

			&:hover {
				background: var(--el-border-color-hover);
			}

			&:active {
				background: var(--el-text-color-placeholder);
			}
		}
	}

	.selected-attributes-display {
		position: sticky;
		top: 0;
		z-index: 10;
		padding: 6px 10px;
		margin: 8px 10px 8px;
		background: rgba(255, 255, 255, 0.95);
		background: linear-gradient(135deg, rgba(236, 245, 255, 0.98) 0%, rgba(230, 244, 255, 0.98) 100%);
		border: 1px solid var(--el-color-primary-light-6);
		border-radius: 4px;
		display: flex;
		align-items: center;
		gap: 6px;
		box-shadow: 0 1px 4px rgba(64, 158, 255, 0.1);
		transition: all 0.3s;
		backdrop-filter: blur(10px);

		&:hover {
			box-shadow: 0 2px 6px rgba(64, 158, 255, 0.15);
		}

		.selected-label {
			font-weight: 600;
			font-size: 12px;
			color: var(--el-color-primary);
			flex-shrink: 0;
		}

		:deep(.el-text) {
			font-size: 12px;
			line-height: 1.4;
		}
	}

	.attributes-container {
		padding: 0 10px 10px;
		.attribute-group {
			margin-bottom: 8px;
			padding: 6px 8px;
			background: var(--el-fill-color-blank);
			border-radius: 4px;
			border: 1px solid var(--el-border-color-lighter);
			transition: all 0.2s;

			&:hover {
				border-color: var(--el-border-color-light);

				.attribute-name .attr-edit {
					opacity: 1;
				}
			}

			&:last-child {
				margin-bottom: 0;
			}

			.attribute-name {
				margin-bottom: 6px;
				padding-bottom: 4px;
				border-bottom: 1px solid var(--el-border-color-lighter);
				display: flex;
				align-items: center;
				justify-content: space-between;

				.attr-label {
					font-size: 12px;
					font-weight: 600;
					color: var(--el-text-color-primary);
					position: relative;
					padding-left: 6px;

					&::before {
						content: '';
						position: absolute;
						left: 0;
						top: 50%;
						transform: translateY(-50%);
						width: 2px;
						height: 10px;
						background: var(--el-color-primary);
						border-radius: 1px;
					}

					&::after {
						content: ':';
						margin-left: 2px;
					}
				}

				.attr-edit {
					font-size: 11px;
					padding: 2px 6px;
					height: 20px;
					opacity: 0;
					transition: all 0.3s ease;
					display: inline-flex;
					align-items: center;

					:deep(.el-icon) {
						font-size: 12px;
						margin-right: 2px;
					}

					&:hover {
						transform: translateX(-2px);
						background: var(--el-color-primary-light-9);
						border-radius: 3px;
					}
				}
			}

			.attribute-values {
				display: flex;
				flex-wrap: wrap;
				gap: 6px;

				.attribute-value-item {
					position: relative;
					padding: 3px 10px;
					border: 1px solid var(--el-border-color);
					border-radius: 4px;
					background: var(--el-fill-color-blank);
					cursor: pointer;
					transition: all 0.2s;
					user-select: none;
					min-height: 24px;
					display: inline-flex;
					align-items: center;
					font-size: 12px;
					color: var(--el-text-color-regular);

					&:hover {
						border-color: var(--el-color-primary);
						color: var(--el-color-primary);
						background: var(--el-color-primary-light-9);
					}

					&.is-selected {
						border-color: var(--el-color-primary);
						background: linear-gradient(135deg, var(--el-color-primary) 0%, var(--el-color-primary-light-3) 100%);
						color: var(--el-color-white);
						font-weight: 500;

						&:hover {
							opacity: 0.9;
						}
					}

					&.is-key-attribute {
						border-width: 1px;
						font-weight: 500;

						&:not(.is-selected) {
							border-color: var(--el-color-warning-light-5);
							background: var(--el-color-warning-light-9);

							&:hover {
								border-color: var(--el-color-warning);
								background: var(--el-color-warning-light-8);
							}
						}
					}

					&.is-disabled {
						cursor: not-allowed;
						opacity: 0.6;

						&:hover {
							border-color: var(--el-border-color);
							color: var(--el-text-color-regular);
							background: var(--el-fill-color-blank);
						}

						&.is-selected:hover {
							border-color: var(--el-color-primary);
							color: var(--el-color-white);
							background: linear-gradient(135deg, var(--el-color-primary) 0%, var(--el-color-primary-light-3) 100%);
							opacity: 0.6;
						}
					}

					.value-text {
						font-size: 12px;
						line-height: 1.2;
					}

					.check-icon {
						margin-left: 4px;
						font-size: 12px;
					}
				}
			}
		}
	}
}

@keyframes checkIn {
	0% {
		opacity: 0;
		transform: scale(0.5);
	}
	50% {
		transform: scale(1.1);
	}
	100% {
		opacity: 1;
		transform: scale(1);
	}
}
</style>
